﻿using NPOI.SS.Formula.Functions;
using Prism.Commands;
using Prism.Events;
using Prism.Services.Dialogs;
using SmartPlant.Core;
using SmartPlant.Core.Mvvm;
using SmartPlant.Model.Biz;
using SmartPlant.Services;
using SmartPlant.Services.Interfaces;
using SmartPlant.WinCore;
using SmartPlant.WinCore.Config;
using SmartPlant.WinCore.Helper;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Input;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.StartPanel;
using Telerik.Windows.Controls.ColorEditor.Pad;
using SmartPlant.Model.DbContext;

namespace SmartPlantApp.ViewModels
{
    public class DomainSelectViewModel : DialogViewModelBase, IDialogAware
    {
        private bool _isBusy;
        private readonly BackgroundWorker backgroundWorker;
        private readonly IOAuthService _authService;
        private readonly IProjectService _projectService;
        private readonly ISysServiceInit _sysServiceInit;
        /// <summary>
        /// 事件聚合器
        /// </summary>
        private readonly IEventAggregator _eventAggregator = null;
        private ObservableCollection<Project> _pros;
        private List<Project> _AllDomains = new List<Project>();
        private DelegateCommand<object> _listSelectChanged;
        private DelegateCommand<object> _enterSystemCommand;
        private DelegateCommand<object> _projectLoadCommand;
        private DelegateCommand<object> _closeWindowCommand;

        //private int _selectedIndex = 0;
        /// <summary>
        /// 选中的domain
        /// </summary>
        private Project _currentSelect = null;
        //private bool _isOpen = false;

        public DomainSelectViewModel(
            IProjectService projectService,
            IOAuthService authService,
            ISysServiceInit sysServiceInit,
            IEventAggregator eventAggregator,
            IDialogService dialog) : base(dialog)
        {
            Title = "项目（Domain）选择";
            _eventAggregator = eventAggregator;
            _sysServiceInit = sysServiceInit;
            _authService = authService;
            _projectService = projectService;
            _pros = new ObservableCollection<Project>();
            backgroundWorker = new BackgroundWorker();
            backgroundWorker.DoWork += this.OnBackgroundWorkerDoWork;
            backgroundWorker.RunWorkerCompleted += OnBackgroundWorkerRunWorkerCompleted;
        }
        /// <summary>
        /// domain列表
        /// </summary>
        public ObservableCollection<Project> Projects
        {
            get
            {
                return _pros;
            }
            set
            {
                SetProperty(ref _pros, value);
            }
        }
        private string _searchText;

        public string searchText
        {
            get { return _searchText; }
            set
            {
                foreach (Project p in _AllDomains)
                {
                    p.shown = true;
                }
                if (string.IsNullOrEmpty(value))
                {
                    Console.WriteLine("");

                }
                else
                {
                    Console.WriteLine("");
                    foreach (Project p in _AllDomains.Where(x => !x.ProjLogName.ToUpper().Contains(value.ToUpper())))
                    {
                        p.shown = false;
                    }
                }
                Projects = new ObservableCollection<Project>(_AllDomains.Where(x => x.shown == true));
                if (Projects.Count == 0)
                {
                    _currentSelect = null;
                }
                SetProperty(ref _searchText, value);
            }
        }


        //public bool IsOpen
        //{
        //    get { return _isOpen; }
        //    set { SetProperty(ref _isOpen, value); }
        //}
        //public int SelectIndex
        //{
        //    get { return _selectedIndex; }
        //    set { SetProperty(ref _selectedIndex, value); }
        //}

        /// <summary>
        /// 选中的domain
        /// </summary>
        public Project CurrentSelect
        {
            get { return _currentSelect; }
            set { SetProperty(ref _currentSelect, value); }
        }

        /// <summary>
        /// 当前是否处理忙碌状态。
        /// </summary>
        public bool IsBusy
        {
            get { return _isBusy; }
            set
            {
                if (this._isBusy != value)
                {
                    this._isBusy = value;

                    if (_isBusy && CurrentSelect == null)
                    {
                        Dialog.ShowAltert("进入系统前请选择工程！！！");
                        _isBusy = false;
                        return;
                    }
                    this.OnPropertyChanged(nameof(IsBusy));

                    if (this._isBusy && !backgroundWorker.IsBusy)
                    {
                        backgroundWorker.RunWorkerAsync();//在onload里绑定给了OnBackgroundWorkerDoWork
                    }
                    else
                    {
                        this._isBusy = false;
                        this.OnPropertyChanged(nameof(IsBusy));
                    }
                }
            }
        }
        /// <summary>
        /// background绑定的处理事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnBackgroundWorkerDoWork(object sender, DoWorkEventArgs e)
        {
            var task = onEnterSystemCommand();
            while (!task.IsCompleted)
            {
                Thread.Sleep(1000);
            }
            e.Result = task.Result;
        }

        private void OnBackgroundWorkerRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            InvokeOnUIThread(() =>
            {
                var result = e.Result as SimpleModel<bool, string>;
                this.IsBusy = false;
                if (result != null && result.v1)
                {
                    GlobalObject.CurrentProject = _currentSelect;
 
                    _eventAggregator.GetEvent<ProjectDomainChangedEvent>().Publish(_currentSelect);//发布一个事件，然后在mainWindowViewModel里去订阅了

                    RaiseRequestClose(new DialogResult(ButtonResult.OK));
                    return;
                }
                else
                {
                    Dialog.ShowAltert(result.v2);
                    _eventAggregator.GetEvent<ProjectDomainChangedEvent>().Publish(null);
                    RaiseRequestClose(new DialogResult(ButtonResult.None));
                    return;
                }
            });
        }
        /// <summary>
        /// 登录Domain按钮，具体逻辑在IsBusy的访问器里
        /// </summary>
        public ICommand EnterSystemCommand
        {
            get
            {
                if (_enterSystemCommand != null) return _enterSystemCommand;
                _enterSystemCommand = new DelegateCommand<object>(o => this.IsBusy = true);
                return _enterSystemCommand;
            }
        }

        public ICommand CloseWindowCommand
        {
            get
            {
                if (_closeWindowCommand != null) return _closeWindowCommand;
                _closeWindowCommand = new DelegateCommand<object>(o => RaiseRequestClose(new DialogResult(ButtonResult.No)));
                return _closeWindowCommand;
            }
        }

        /// <summary>
        /// loaded之后触发
        /// </summary>
        public ICommand ProjectLoadCommand
        {
            get
            {
                if (_projectLoadCommand != null) return _projectLoadCommand;
                _projectLoadCommand = new DelegateCommand<object>(onProjectLoadCommand);
                return _projectLoadCommand;
            }
        }
        /// <summary>
        /// 选择不同的domain后
        /// </summary>
        public ICommand ListSelectChanged
        {
            get
            {
                if (_listSelectChanged != null) return _listSelectChanged;
                _listSelectChanged = new DelegateCommand<object>(listSelectChanged);
                return _listSelectChanged;
            }
        }

        private void listSelectChanged(object sender)
        {
            SelectionChangedEventArgs args = sender as SelectionChangedEventArgs;
            if (args == null)
            {
                _currentSelect = null;
                return;
            }
            if (args.AddedItems.Count < 1)
            {
                _currentSelect = null;
                return;
            }
            _currentSelect = args.AddedItems[0] as Project;
        }

        private async void onProjectLoadCommand(object sender)
        {
            var pros = await _projectService.GetDomainsAsync();
            Projects.AddRange(pros);
            _AllDomains.AddRange(pros);
        }


        /// <summary>
        /// 登录domain
        /// </summary>
        /// <returns></returns>
        private async Task<SimpleModel<bool, string>> onEnterSystemCommand()
        {
            try
            {
                await _projectService.DomainConnectAsync(CurrentSelect.ProjLogName, CurrentSelect.ProjLogPass);
                await _sysServiceInit.InitAsync(_currentSelect.ProjId.ToString());
                GlobalObject.UserRightDatas = await _authService.GetUserRightDatasAsync(_currentSelect.ProjId.ToString(), GetUser());
                return new SimpleModel<bool, string> { v1 = true, v2 = "登陆成功。" };
            }
            catch (Exception x)
            {
                string msg = $"服务端初化失败：{x.Message}";
                LoggerHelper.Current.Error(msg, x);
                Dialog.ShowAltert(msg);
                return new SimpleModel<bool, string> { v1 = false, v2 = msg }; ;
            }
        }

        /// <summary>
        /// 从配置文件拿
        /// </summary>
        private string GetUser()
        {
            SysConfig sysConfig = ConfigHelper.ReadConfig();
            string loginName = sysConfig.LoginName;
            return loginName;
        }
    }
}
